package com.weasel.security.helper;

import com.weasel.helper.TimeHelper;
import com.weasel.security.domain.user.User;
import com.weasel.security.shiro.ShiroRealm;
import com.weasel.security.shiro.cache.ShiroCacheManager;
import com.weasel.security.shiro.cache.repository.UserSessionRelationCacheService;
import com.weasel.security.shiro.cache.repository.impl.UserSessionRelationLocalCacheServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Dylan
 * @time 2013-8-12
 */
public class ShiroSecurityHelper {
	
	private final static Logger log = LoggerFactory.getLogger(ShiroSecurityHelper.class);

	@Deprecated
	private static SessionDAO sessionDAO;

	private static ShiroCacheManager cacheManager;

	private static UserSessionRelationCacheService userSessionRelationCacheService;


	/**
	 * 从cache拿当前user
	 * 
	 * @return
	 */
	public static User getCurrentUser() {

		Subject subject = getSubject();
		PrincipalCollection collection = subject.getPrincipals();
		if (null != collection && !collection.isEmpty()) {
			return (User) collection.iterator().next();
		}
		return null;
	}

	/**
	 * 获得当前用户名
	 * 
	 * @return
	 */
	public static String getCurrentUsername() {
		User user = getCurrentUser();
		return null != user ? user.getUsername() : null;
	}

	/**
	 * 
	 * @return
	 */
	public static Session getSession() {
		return SecurityUtils.getSubject().getSession();
	}

	/**
	 * 
	 * @return
	 */
	public static String getSessionId() {
		Session session = getSession();
		if (null == session) {
			return null;
		}
		return getSession().getId().toString();
	}
	
	/**此方法会会遍历所有的session
	 * @param username
	 * @return
	 */
	public static Session getSessionByUsername(String username){
		/*Collection<Session> sessions = sessionDAO.getActiveSessions();
		for(Session session : sessions){
			if(null != session && StringUtils.equals(String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)), username)){
				return session;
			}
		}*/
		Cache<Object, Object> sessionCache = getSessionCache();
		String sessionid = userSessionRelationCacheService.getSessionid(username);
		return (Session) sessionCache.get(sessionid);
	}
	
	/**踢除用户,此方法会会遍历所有的session
	 * @param username
	 */
	public static void kickOutUser(String username){
		Session session = getSessionByUsername(username);
		if(null != session && !StringUtils.equals(String.valueOf(session.getId()), ShiroSecurityHelper.getSessionId())){
			ShiroAuthorizationHelper.clearAuthenticationInfo(session.getId());
			log.info("############## success kick out user 【{}】 ------ {} #################", username,TimeHelper.getCurrentTime());
		}
	}

	/**将用户和session绑定
	 * @param username
	 */
	public static void bindUserAndSession(String username){
		bindUserAndSession(username,getSessionId());
	}

	/** 将用户和session绑定
	 * @param username
	 * @param sessionid
	 */
	public static void bindUserAndSession(String username,String sessionid){
		userSessionRelationCacheService.bind(username, sessionid);
	}

	/**获取session缓存
	 * @return
	 */
	public static Cache<Object, Object> getSessionCache(){
		//shiro-activeSessionCache 为shiro自义cache名，该名在org.apache.shiro.session.mgt.eis.CachingSessionDAO抽象类中定义
		//如果要改变此名，可以将名称注入到sessionDao中，例如注入到CachingSessionDAO的子类EnterpriseCacheSessionDAO类中
		return cacheManager.getCache("shiro-activeSessionCache");
	}

	/**获取用户认证信息缓存
	 * @return
	 */
	public static Cache<Object, Object> getAuthorizationCache(){
		//ShiroCasRealm.authorizationCache 为shiro自义cache名(shiroCasRealm为我们定义的reaml类的类名)
		return cacheManager.getCache(ShiroRealm.REALM_NAME+".authorizationCache");
	}

	/**获取缓存管理
	 * @return
	 */
	public static ShiroCacheManager getCacheManager() {
		return cacheManager;
	}

	/**
	 * @param _cacheManager
	 */
	public static void initStaticField(ShiroCacheManager _cacheManager){
		cacheManager = _cacheManager;
		userSessionRelationCacheService = SpringBeanHolder.getBean(UserSessionRelationCacheService.class);
		if(null == userSessionRelationCacheService){
			userSessionRelationCacheService = new UserSessionRelationLocalCacheServiceImpl();
		}
	}

	@Deprecated
	public static void initStaticField(SessionDAO sessionDAO){
		ShiroSecurityHelper.sessionDAO = sessionDAO;
	}

	/**
	 * 判断当前用户是否已通过认证
	 * @return
	 */
	public static boolean hasAuthenticated() {
		return getSubject().isAuthenticated();
	}

	private static Subject getSubject() {
		return SecurityUtils.getSubject();
	}


}
